#include "board.h"

#include <QPainter>
#include <QMouseEvent>
#include <QMessageBox>

//棋盘类
Board::Board(QWidget *parent) : QWidget(parent)
{
    //半径
    stone_radius = 15;

    //窗体大小
    this->resize(stone_radius * 20, stone_radius * 22);

    //初始化棋子
    for(int i = 0;i < 32; i++)
    {
        board_stones[i].stone_init(i);
    }
    move_id = -1;
    move_side = true;
}



Board::~Board()
{

}

/*
 * 画棋盘
 * 象棋棋盘十横九竖
 * 九宫格
 * 炮，兵位置标记
 * 楚河汉界
 */
void Board::paintEvent(QPaintEvent *)
{
    //画笔
    QPainter board_painter(this);

    //棋子直径
    int stone_diameter = stone_radius * 2;

    //画十条横线
    for(int i = 1; i <= 10; i++)
    {
        board_painter.drawLine(QPoint(stone_diameter, i * stone_diameter), QPoint(9 * stone_diameter, i * stone_diameter));
    }

    //画九条竖线
    for(int i = 1; i <= 9; i++)
    {
        if(i == 1 || i == 9)
        {
            board_painter.drawLine(QPoint(i * stone_diameter, stone_diameter), QPoint(i * stone_diameter, 10 * stone_diameter));
        }
        else
        {
            board_painter.drawLine(QPoint(i * stone_diameter, stone_diameter), QPoint(i * stone_diameter, 5 * stone_diameter));
            board_painter.drawLine(QPoint(i * stone_diameter, 6 * stone_diameter), QPoint(i * stone_diameter, 10 * stone_diameter));
        }
    }

    //画九宫格
    board_painter.drawLine(QPoint(4 * stone_diameter, 1 * stone_diameter), QPoint(6 * stone_diameter, 3 * stone_diameter));
    board_painter.drawLine(QPoint(6 * stone_diameter, 1 * stone_diameter), QPoint(4 * stone_diameter, 3 * stone_diameter));

    board_painter.drawLine(QPoint(4 * stone_diameter, 8 * stone_diameter), QPoint(6 * stone_diameter, 10 * stone_diameter));
    board_painter.drawLine(QPoint(6 * stone_diameter, 8 * stone_diameter), QPoint(4 * stone_diameter, 10 * stone_diameter));

    //画32颗棋子
    for(int i = 0; i < 32; i++)
    {
        draw_stone(board_painter, i);
    } 
}

void Board::draw_stone(QPainter &stone_painter, int draw_id)
{
    if(!board_stones[draw_id].stone_life)
    {
        return;
    }

    QPoint draw_point = point(draw_id);
    QRect draw_rect = QRect(draw_point.x() - stone_radius, draw_point.y() - stone_radius, stone_radius * 2, stone_radius * 2);

    //设置棋子填充颜色
    if(draw_id == move_id)
    {
        stone_painter.setBrush(QBrush(Qt::blue));
    }
    else
    {
        stone_painter.setBrush(QBrush(Qt::yellow));
    }
    //设置棋子轮廓颜色
    stone_painter.setPen(Qt::black);

    stone_painter.drawEllipse(draw_point, stone_radius, stone_radius);

    //设置棋子字体颜色
    if(board_stones[draw_id].stone_side)
    {
        stone_painter.setPen(Qt::red);
    }
    else
    {
        stone_painter.setPen(Qt::green);
    }
    stone_painter.setFont(QFont("SimHei", stone_radius, -1, false));
    stone_painter.drawText(draw_rect, board_stones[draw_id].stone_name(), QTextOption(Qt::AlignCenter));
}


QPoint Board::point(int x, int y)
{
    QPoint p;
    p.rx() = (x + 1) * stone_radius * 2;
    p.ry() = (y + 1) * stone_radius * 2;
    return p;
}

QPoint Board::point(int id)
{
    return point(board_stones[id].stone_x, board_stones[id].stone_y);
}


bool Board::point_xy(QPoint p, int &x, int &y)
{
    x = (p.x() / stone_radius - 1) / 2;
    y = (p.y() / stone_radius - 1) / 2;
    if (x == -1 || x == 9 || y == -1 || y == 10)
    {
        return false;
    }
    else
    {
        return true;
    }
}

int Board::xy_id(int x, int y)
{
    int id = -1;
    for(int i = 0;i < 32;i++)
    {
        //判断坐标上的棋子
        if(board_stones[i].stone_x == x && board_stones[i].stone_y == y && board_stones[i].stone_life)
        {
            id = i;
            break;
        }
    }
    return id;
}
int Board::line_stone(int x, int y)
{
    //同一直线两点之间的棋子数
    int stone_count = 0;

    if(board_stones[move_id].stone_x == x)
    {
        int max = board_stones[move_id].stone_y > y ? board_stones[move_id].stone_y : y;
        int min = board_stones[move_id].stone_y > y ? y : board_stones[move_id].stone_y;

        for (int j = min + 1;j < max; j++)
        {
            for(int i = 0;i < 32;i++)
            {
                if(board_stones[i].stone_x == x && board_stones[i].stone_y == j && board_stones[i].stone_life)
                {
                    stone_count++;
                    continue;
                }
            }
        }
    }
    if(board_stones[move_id].stone_y == y)
    {
        int max = board_stones[move_id].stone_x > x ? board_stones[move_id].stone_x : x;
        int min = board_stones[move_id].stone_x > x ? x : board_stones[move_id].stone_x;

        for (int j = min + 1;j < max; j++)
        {
            for(int i = 0;i < 32;i++)
            {
                if(board_stones[i].stone_x == j && board_stones[i].stone_y == y && board_stones[i].stone_life)
                {
                    stone_count++;
                    continue;
                }
            }
        }
    }

    return stone_count;
}

bool Board::jiang_move(int x, int y)
{
    //对将
    int kill_id = xy_id(x, y);

    if(((move_id == 0 && kill_id == 16) || (move_id == 16 && kill_id == 0)) && board_stones[move_id].stone_x == board_stones[kill_id].stone_x && line_stone(x, y) == 0)
    {
        return true;
    }
    else
    {
        //将不能出九宫格
        if(x > 5 || x < 3)
        {
            return false;
        }
        if(board_stones[move_id].stone_side)
        {
            if(y < 7)
            {
                return false;
            }
        }
        else
        {
            if(y > 2)
            {
                return false;
            }
        }

        //将只能走一格
        int d = 10 * abs(board_stones[move_id].stone_x - x) + abs(board_stones[move_id].stone_y - y);
        if(d != 10 && d != 1)
        {
            return false;
        }
        return true;
    }
}
bool Board::che_move(int x, int y)
{
    //在同一直线上
    if(board_stones[move_id].stone_x != x && board_stones[move_id].stone_y != y)
    {
        return false;
    }
    //中间没有棋子
    if(line_stone(x, y) != 0)
    {
        return false;
    }
    return true;
}
bool Board::ma_move(int x, int y)
{
    int d = 10 * abs(board_stones[move_id].stone_x - x) + abs(board_stones[move_id].stone_y - y);
    if(d != 12 && d != 21)
    {
        return false;
    }
    //马别体
    if(d == 12)
    {
        if(xy_id(board_stones[move_id].stone_x, (board_stones[move_id].stone_y + y) / 2) != -1)
        {
            return false;
        }
    }
    if(d == 21)
    {
        if(xy_id((board_stones[move_id].stone_x + x) / 2, board_stones[move_id].stone_y) != -1)
        {
            return false;
        }
    }

    return true;
}
bool Board::pao_move(int x, int y)
{
    //在同一直线上
    if(board_stones[move_id].stone_x != x && board_stones[move_id].stone_y != y)
    {
        return false;
    }

    //判断是否吃棋
    bool kill = false;
    for(int i = 0;i < 32;i++)
    {
        if(board_stones[i].stone_x == x && board_stones[i].stone_y == y && board_stones[i].stone_life)
        {
            kill = true;
            break;
        }
    }
    if(kill)
    {
        //隔一棋子吃棋子
        if(line_stone(x, y) != 1)
        {
            return false;
        }
    }
    else
    {
        //中间没有棋子
        if(line_stone(x, y) != 0)
        {
            return false;
        }
    }
    return true;

}
bool Board::shi_move(int x, int y)
{
    //士不能出九宫格
    if(x > 5 || x < 3)
    {
        return false;
    }
    if(board_stones[move_id].stone_side)
    {
        if(y < 7)
        {
            return false;
        }
    }
    else
    {
        if(y > 2)
        {
            return false;
        }
    }
    //士走一格对角线
    int d = 10 * abs(board_stones[move_id].stone_x - x) + abs(board_stones[move_id].stone_y - y);
    if(d != 11)
    {
        return false;
    }
    return true;
}
bool Board::xiang_move(int x, int y)
{
    //相不能过河
    if(board_stones[move_id].stone_side)
    {
        if(y < 5)
        {
            return false;
        }
    }
    else
    {
        if(y > 4)
        {
            return false;
        }
    }
    //相走田
    int d = 10 * abs(board_stones[move_id].stone_x - x) + abs(board_stones[move_id].stone_y - y);
    if(d != 22)
    {
        return false;
    }
    //压相心
    if(xy_id((board_stones[move_id].stone_x + x) / 2, (board_stones[move_id].stone_y + y) / 2) != -1)
    {
        return false;
    }
    return true;

}
bool Board::zu_move(int x, int y)
{

    //判断是否过河
    //卒不能后退
    bool river = false;
    if(board_stones[move_id].stone_side)
    {
        if(y > board_stones[move_id].stone_y)
        {
            return false;
        }
        if(board_stones[move_id].stone_y < 5)
        {
            river = true;
        }

    }
    else
    {
        if(y < board_stones[move_id].stone_y)
        {
            return false;
        }
        if(board_stones[move_id].stone_y > 4)
        {
            river = true;
        }

    }

    //没有过河的卒不能左右走
    if(!river)
    {
        if(board_stones[move_id].stone_x != x)
        {
            return false;
        }
    }
    //卒只能走一格
    int d = 10 * abs(board_stones[move_id].stone_x - x) + abs(board_stones[move_id].stone_y - y);
    if(d != 10 && d != 1)
    {
        return false;
    }
    return true;
}

bool Board::can_move(int x, int y)
{
    switch (board_stones[move_id].stone_type) {
    case 0:
        return jiang_move(x, y);
        break;
    case 1:
        return che_move(x, y);
        break;
    case 2:
        return ma_move(x, y);
        break;
    case 3:
        return pao_move(x, y);
        break;
    case 4:
        return shi_move(x, y);
        break;
    case 5:
        return xiang_move(x, y);
        break;
    case 6:
        return zu_move(x, y);
        break;
    default:
        return false;
        break;
    }
}



void Board::stone_move(int x, int y, int id)
{
    if(can_move(x, y))
    {
        //吃棋
        if(id != -1)
        {
            board_stones[id].stone_life = false;
        }
        //移动的棋子坐标变化
        board_stones[move_id].stone_x = x;
        board_stones[move_id].stone_y = y;

        //走完后
        move_id = -1;
        move_side = !move_side;
    }

}





void Board::player_move(QPoint p)
{

    //鼠标点击坐标
    int click_x, click_y;
    //判断坐标是否在棋盘范围内
    bool inout = point_xy(p, click_x, click_y);
    if(!inout)
    {
        return;
    }
    //点击的棋子
    int click_id = xy_id(click_x, click_y);
    //一步走棋分两次点击棋子
    if(move_id == -1)
    {
        //确定要移动的棋子
        if(click_id != -1 && move_side == board_stones[click_id].stone_side)
        {
            move_id = click_id;
        }
    }
    else
    {
        //确定要移动的棋子，如果是己方棋子，就是更换移动的棋子
        if(click_id != -1 && move_side == board_stones[click_id].stone_side)
        {
            move_id = click_id;
        }
        else
        {
            stone_move(click_x, click_y, click_id);
        }
    }
    //棋盘显示更新
    update();

    //检测胜败
    win_fail();
}

void Board::mouseReleaseEvent(QMouseEvent *me)
{
    //鼠标左键走棋
    if(me->button() != Qt::LeftButton)
    {
        return;
    }
    //玩家走棋
    player_move(me->pos());
}


void Board::save_step(int move_id, int kill_id, int from_x, int from_y, int to_x, int to_y, QVector<Step *> &steps)
{
    Step* step = new Step;
    step->move_id = move_id;
    step->kill_id = kill_id;
    step->from_x = from_x;
    step->from_y = from_y;
    step->to_x = to_x;
    step->to_y = to_y;

    steps.append(step);

}


void Board::win_fail()
{
    if(!board_stones[0].stone_life)
    {
        QMessageBox::about(this, "胜利", "胜利");
        this->close();
    }
    if(!board_stones[16].stone_life)
    {
        QMessageBox::about(this, "失败", "失败");
        this->close();
    }
}


